﻿using SynapseGaming.SunBurn.Framework.Graphics.Effects;
using SynapseGaming.SunBurn.Framework.Graphics.Textures;
using SynapseGaming.SunBurn.Framework.Primitives;
namespace GameLibrary
{
    public class TerrainEffect
    {
        private Effect baseEffect;

        #region Properties
        private EffectParameter worldViewProjParam;

        public Matrix WorldViewProj
        {
            set { worldViewProjParam.SetValue(value); }
        }

        private EffectParameter worldParam;

        public Matrix World
        {
            set { worldParam.SetValue(value); }
        }

        private EffectParameter viewParam;

        public Matrix View
        {
            set { viewParam.SetValue(value); }
        }

        private EffectParameter[] textureParams;

        internal EffectParameter[] TextureParams
        {
            get { return textureParams; }
            set { textureParams = value; }
        }

        private EffectParameter[] textureScaleParams;

        internal EffectParameter[] TextureScaleParams
        {
            get { return textureScaleParams; }
            set { textureScaleParams = value; }
        }

        private EffectParameter colormapParam;

        internal Texture2D Colormap
        {
            set 
            { 
                colormapParam.SetValue(value);

                if (value != null)
                {
                    colorMapSize = value.Width;
                }
            }
        }

        private EffectParameter groundCursorPositionParam;

        internal Vector3 GroundCursorPosition
        {
            set { groundCursorPositionParam.SetValue(value); }
        }

        private EffectParameter groundCursorSizeParam;

        internal float GroundCursorSize
        {
            set { groundCursorSizeParam.SetValue(value); }
        }

        private EffectParameter lightDirection;

        internal Vector3 LightDirection
        {
            set { lightDirection.SetValue(value); }
        }

        private EffectParameter ambientLightParam;

        internal Vector3 AmbientLight
        {
            set { ambientLightParam.SetValue(value); }
        }

        private EffectParameter lightPowerParam;

        internal float LightPower
        {
            set { lightPowerParam.SetValue(value); }
        }

        private EffectParameter colorMapSizeParam;

        private float colorMapSize
        {
            set { colorMapSizeParam.SetValue(value); }
        }

        private EffectTechnique texturedTechnique;

        internal EffectTechnique TexturedTechnique
        {
            get { return texturedTechnique; }
            set { texturedTechnique = value; }
        }

        private EffectParameter drawCursor;

        internal bool DrawCurosr
        {
            set { drawCursor.SetValue((float)(value ? 1 : 0)); }
        }

        #endregion

        public TerrainEffect(Effect cloneSource)
        {
            baseEffect = cloneSource;

            InitializeComponent();

            baseEffect.SetTechnique(texturedTechnique);
            World = Matrix.Identity;
        }

        private void InitializeComponent()
        {
            texturedTechnique = baseEffect.Techniques["TransformTexture"];

            this.worldViewProjParam = baseEffect.Parameters["WorldViewProj"];
            this.worldParam = baseEffect.Parameters["World"];
            this.viewParam = baseEffect.Parameters["View"];

            TextureParams = new EffectParameter[5];
            textureScaleParams = new EffectParameter[5];
            for (int i = 0; i < TextureParams.Length; i++)
            {
                TextureParams[i] = baseEffect.Parameters["t" + i];
                textureScaleParams[i] = baseEffect.Parameters["t" + i + "scale"];
            }

            this.colormapParam = baseEffect.Parameters["colormap"];
            this.groundCursorPositionParam = baseEffect.Parameters["groundCursorPosition"];
            this.groundCursorSizeParam = baseEffect.Parameters["groundCursorSize"];
            this.lightDirection = baseEffect.Parameters["lightDirection"];
            this.ambientLightParam = baseEffect.Parameters["ambientLight"];
            this.lightPowerParam = baseEffect.Parameters["lightPower"];

            this.colorMapSizeParam = baseEffect.Parameters["ColorMapSize"];

            this.drawCursor = baseEffect.Parameters["drawCursor"];
            DrawCurosr = true;
        }

        public void SetTexture(int channel, Texture2D texture)
        {
            textureParams[channel].SetValue(texture);
        }
        public void SetUVScale(int channel, float scale)
        {
            textureScaleParams[channel].SetValue(scale);
        }

        internal void Apply()
        {
            baseEffect.Apply();
        }
    }
}
